/**
 * 反射获取加载资源中的类
 * ibio-develop
 * 2009-3-4 10:51
 */
package com.ibio8.utils {
	import flash.display.Loader;
	import flash.net.URLRequest;
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.events.IOErrorEvent;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.ByteArray;
	/**
	 * 反射获取加载资源中的类。
	 * 
	 * <p>
	 * 通常用来获取加载 swf 中的资源或类。
	 * </p>
	 */
	public class Reflection {
		/** @private **/
		protected var m_loader:Loader;
		/** @private **/
		protected var m_onResult:Function;
		/** @private **/
		protected var m_onProgress:Function;
		/** @private **/
		protected var m_onError:Function;
		/** @private **/
		protected var m_resultParams:Array;
		
		/**
		 * 加载完毕的回调函数
		 * @param	onResult	加载成功回调
		 * @param	onProgress	加载进度回调（可选）
		 * @param	onError		加载失败回调（可选）
		 * @param	...rest	回调函数的参数（可选）
		 */
		public function onResult(onResult:Function, onProgress:Function = null, onError:Function = null, ...rest):void {
			m_onResult = onResult;
			m_onProgress = onProgress;
			m_onError = onError;
			m_resultParams = rest;
		}
		
		/**
		 * 加载指定 url 的内容
		 * @param	data	指定的 url 或者二进制数据
		 */
		public function loadContent(data:Object):void {
			m_loader = new Loader();
			m_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadedHandler);
			m_loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgressHandler);
			m_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOErrorHandler);
			var context:LoaderContext = new LoaderContext();
			/*加载到同域(共享库)*/
			context.applicationDomain = ApplicationDomain.currentDomain;
			if (data is ByteArray) {
				try {
					m_loader.loadBytes(data as ByteArray, context);
				}catch (e:Error) {
					trace("Reflection::loadContent->", e.message);
				}
			}else if (data is String) {
				try {
					m_loader.load(new URLRequest(data as String), context);
				}catch (e:Error) {
					trace("Reflection::loadContent->", e.message);
				}
			}
		}
		
		/**
		 * 获取指定名称的类
		 * @param	name	名称
		 * @return			该类
		 */
		public function getClass(name:String):Class {
			var resRef:Class;
			try{
				resRef = m_loader.contentLoaderInfo.applicationDomain.getDefinition(name) as Class;
			} catch (e:ReferenceError) {
				trace("Reflection::getClass->在共享库里没有找到 [" + name + "] 类。" + e.message);
			}
			return resRef;
		}
		
		/**
		 * 卸载资源
		 */
		public function remove():void {
			if (m_loader) {
				removeListener();
				try {
					m_loader.close();
				}catch (e:Error) {
					trace("Reflection::remove.close->" + e.message);
				}
				try {
					m_loader.unload();
				}catch (e:Error) {
					trace("Reflection::remove.unload->" + e.message);
				}
			}
		}
		
		/**
		 * 加载成功后的回调函数
		 * @param	e	Flash 事件（Event）
		 */
		protected function onLoadedHandler(e:Event):void {
			removeListener();
			//加载成功后的回调函数
			if (m_onResult != null) {
				if (m_resultParams.length == 0) {
					m_onResult();
				}else {
					m_onResult.apply(null, m_resultParams);
				}
			}
		}
		
		/**
		 * 加载过程中回调
		 * @param	e	加载进度事件
		 */
		protected function onProgressHandler(e:ProgressEvent):void {
			//Math.round(e.bytesLoaded / e.bytesTotal * 100);
			if (m_onProgress != null) {
				m_onProgress(e.bytesLoaded / e.bytesTotal);
			}
		}
		
		/**
		 * 加载错误回调函数
		 * @param	e	输入或输出错误事件
		 */
		protected function onIOErrorHandler(e:IOErrorEvent):void {
			//trace("加载错误");
			removeListener();
			if (m_onError != null) {
				m_onError();
			}
		}
		
		/** @private **/
		protected function removeListener():void {
			m_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoadedHandler);
			m_loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, onProgressHandler);
			m_loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onIOErrorHandler);
		}
	}
}